package com.tungse;

import java.util.Iterator;
import java.util.function.Predicate;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

public class 素数计算 {//PrimeGenerator {

    // 生成奇数的迭代器 (3, 5, 7, 9, ...)
    static class OddIterator implements Iterator<Integer> {
        private int current = 1;

        @Override
        public boolean hasNext() {
            return true; // 无限序列
        }

        @Override
        public Integer next() {
            current += 2;
            return current;
        }
    }

    // 素数生成器
    static class PrimeIterator implements Iterator<Integer> {
        private Iterator<Integer> sequence;
        private int lastPrime = 2;
        private boolean firstYield = true;

        public PrimeIterator() {
            sequence = new OddIterator(); // 初始序列
        }

        @Override
        public boolean hasNext() {
            return true; // 无限序列
        }

        @Override
        public Integer next() {
            if (firstYield) {
                firstYield = false;
                return lastPrime; // 返回第一个素数 2
            }

            while (true) {
                int candidate = sequence.next();
                if (isPrime(candidate)) {
                    lastPrime = candidate;
                    // 添加新的过滤器：移除当前素数的倍数
                    sequence = filter(sequence, x -> x % candidate != 0);
                    return candidate;
                }
            }
        }

        private boolean isPrime(int n) {
            // 检查是否能被之前的素数整除
            for (int p = 2; p * p <= n; p++) {
                if (n % p == 0) return false;
            }
            return true;
        }

        // 创建过滤迭代器
        private Iterator<Integer> filter(Iterator<Integer> source, Predicate<Integer> predicate) {
            Iterable<Integer> iterable = () -> source;
            Stream<Integer> stream = StreamSupport.stream(iterable.spliterator(), false);
            return stream.filter(predicate).iterator();
        }
    }

    public static void main(String[] args) {
        Iterator<Integer> primes = new PrimeIterator();

        while (true) {
            int prime = primes.next();
            if (prime < 100) {
                System.out.println(prime);
            } else {
                break;
            }
        }
    }
}